<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <script>
        // ES5实现继承
        // Object.create()方法创建一个新对象，使用现有的对象来提供新创建的对象的__proto__

        function Person(name, age) {
            this.name = name;
            this.age = age;
        }
        Person.prototype.getName = function () {
            return this.name
        }
        Person.prototype.getAge = function () {
            return this.age;
        }

        function Student(name, age, grade) {
            // 构造函数继承
            Person.call(this, name, age);
            this.grade = grade;
        }

        // // Object.Create 实现机制
        // Object.myCreate = function (obj) {
        //     let emptyObj = {};
        //     // 但是__proto__在IE下已被禁用，兼容性不好，所以我们要想其他方法
        //     emptyObj.__proto__ = obj;
        //     return emptyObj;
        // }
        Object.myCreate2 = function (obj, propertiesObject) {

            function fun2() { }
            fun2.prototype = obj;


            let tempObj = new fun2();

            let ownkeys=Reflect.ownKeys(propertiesObject);
            for (let propertyName of ownkeys) {
                Reflect.defineProperty(tempObj, propertyName, propertiesObject[propertyName]);
            }
            return tempObj;

        }

        Student.prototype = Object.myCreate2(Person.prototype, {
            // 不要忘了重新指定构造函数 这个是必须的
            constructor: {
                value: Student
            },
            foo: {
                writable: true,
                configurable: true,
                value: "hello"
            },
            getGrade: {
                value: function () {
                    return this.grade
                }
            }
        }
        )

        // 语法 Object.create(proto，[propertiesObject])
        // proto 该参数是一个对象， 会作为新对象的原型对象
        // propertiesObject 该参数是一个属性描述对象，它所描述的对象属性，会添加到新对象中，作为该新对象自身的属性。


        // // 原型继承
        // Student.prototype = Object.create(Person.prototype, {
        //     // 不要忘了重新指定构造函数 这个是必须的
        //     constructor: {
        //         value: Student
        //     },
        //     foo: {
        //         writable: true,
        //         configurable: true,
        //         value: "hello"
        //     },
        //     getGrade: {
        //         value: function () {
        //             return this.grade
        //         }
        //     }
        // })

        console.log(Student.prototype);

        // var s1 = new Student('ming', 22, 5);
        // console.log(s1);// s1.__proto__= Student.prototype

// console.log(s1.getName());  // ming
// console.log(s1.getAge());   // 22
// console.log(s1.getGrade()); // 5
// console.log(s1.foo); // hello

        // function MyArray() {
        //     Array.apply(this, arguments);
        // }

        // MyArray.prototype = Object.create(Array.prototype, {
        //     constructor: {
        //         value: MyArray,
        //         writable: true,
        //         configurable: true,
        //         enumerable: true
        //     }
        // });

        // var colors = new MyArray();
        // colors[0] = "red";
        // colors.length  // 0

        // colors.length = 0;
        // colors[0]  // "red"
    </script>
</head>

<body>

</body>

</html>